package com.manuserve.mountainduck.kernel;

import android.graphics.PointF;

import java.util.Calendar;
import java.util.Hashtable;

/**
 * Created by xmanoux on 09/03/14.
 */
public class Univers {

    float iPointerIHM = 0.0f ;
    //premiere case en bas à gauche
    float jPointerIHM = 0.0f ;
    //premiere case en bas à gauche
    Hashtable<Integer,Colonne> data = new Hashtable<Integer, Colonne>() ;
    float pente = 0.0f ;
    int lastCreatedX = -1 ;
    int oldestCreatedX = - 1 ;
    int selectedCol = -1 ;
    float deviationSeed = 1.3f ;
    boolean isRecord = false ;
    boolean isOwnRecord = false ;
    Duck duck = null ;
    float g = (float) ( 9.8/(1000*1000) ) ;
    boolean ignition = false ; //uniquement pour lancer le redémarrage du jeu
    boolean endJourn = false ;
    GameBoard ihm = null ;





    public Univers(GameBoard ihm) {
        Univers thisUnivers = this  ;
        thisUnivers.ihm = ihm ;
        thisUnivers.ignition = true ;
        ihm.univers = this ;
        thisUnivers.pente = 0.5f ;
        thisUnivers.newGame();
    }



    public int spriteInfoProvider(Float fi,Float fj) {
            Univers thisUnivers = this ;
            int i = (int) Math.floor(fi);
            int j = (int) Math.floor(fj);
            while(! thisUnivers.data.containsKey(i) ){
                thisUnivers.newTerrainTo(i);
            }
            if(thisUnivers.data.get(i).height >= j ) {
                return thisUnivers.data.get(i).type ;
            } else {
                return 0 ;
            }
        }

        /**
         *
         * @param iMin limite gauche du terrain de jeu à créer
         * @param iMax limite droite du terrain de jeu à créer
         * @param jMin hauteur correspondante à la limite gauche
         */
        public void createTerrain(int iMin,int iMax,float jMin) {
            Univers thisUnivers = this ;
            int k  ;
            for (k = thisUnivers.oldestCreatedX ; k < Math.floor(thisUnivers.iPointerIHM) ; k++ ) {
                thisUnivers.data.remove(k);
            }
            thisUnivers.oldestCreatedX = (int) Math.floor((float) thisUnivers.iPointerIHM) ;
            for (k = iMin ; k <= iMax ; k++ ) {
                if(thisUnivers.oldestCreatedX==-1) {
                    thisUnivers.oldestCreatedX = k ;
                }
                //hauteur moyenne attendue
                thisUnivers.lastCreatedX = k  ;
                float height = 1+Math.round(jMin + (k-iMin)*thisUnivers.pente) ;
                //Déviation
                height += Math.round((Math.random()-0.5)*thisUnivers.deviationSeed*thisUnivers.ihm.discrWidth*thisUnivers.pente);
                thisUnivers.data.put(k,new Colonne(Math.round(height), 1 ));
            }
        }


        public void newTerrainTo(int i) {
            Univers thisUnivers = this ;
            thisUnivers.createTerrain(
                    thisUnivers.lastCreatedX+1,
                    i+1 ,
                    this.jPointerIHM+thisUnivers.pente*(thisUnivers.lastCreatedX+1-thisUnivers.iPointerIHM)
            );
        }

    public PointF physics(float timeIntervallSinceLastCalc) {
            Univers thisUnivers = this ;
            if(thisUnivers.ignition) {
                thisUnivers.newGame();
            }
            if(this.endJourn) {
                thisUnivers.ihm.generiqueAudio.stop();
                //effondrement de la colonne
                if(thisUnivers.duck.j >= thisUnivers.jPointerIHM  ){
                    thisUnivers.data.get((int) Math.floor(thisUnivers.duck.i)).height -- ;
                    thisUnivers.duck.j -- ;
                } else {
                    thisUnivers.ihm.playAudioUrgence();
                    thisUnivers.ihm.animation = false ;
                    thisUnivers.ihm.score = (int) Math.floor(thisUnivers.jPointerIHM) ;
                    thisUnivers.ihm.isLostScreen = true ;
                    thisUnivers.ignition = true ;

                    thisUnivers.ihm.paused = true ;
                    thisUnivers.ihm.pauseSetTime = Calendar.getInstance().getTimeInMillis();
                }
            }
            float oldIPointer = thisUnivers.iPointerIHM ;
            thisUnivers.duck.physics(timeIntervallSinceLastCalc);
            float distance = thisUnivers.duck.i - thisUnivers.iPointerIHM ;
            if(distance <= 0) {
                //Si le canard a dépassé la gauche de l'écran, on rattrape illico
                thisUnivers.iPointerIHM = thisUnivers.duck.i ;
            } else {
                //Plus le canard est loin du bord gauche visible, plus vite on va décaler la caméra sur la droite  //Le décalage maximal est donc de distance    //on va diviser distance par quelque chose compris entre 1 et l'infni. infini à gauche, 1 à droite             //distanceMax/distance va donner 1 si on s'approche du bord droit de l'écran, infini vers le gauche. On met au pif à une puissance pour dramatiser l'effet
                thisUnivers.iPointerIHM = (float) (  thisUnivers.iPointerIHM + distance/ Math.pow(thisUnivers.ihm.discrWidth / distance,4 ) );
            }
            float translationX = thisUnivers.iPointerIHM-oldIPointer ;

            float translationY = thisUnivers.pente * translationX ;

            thisUnivers.jPointerIHM+=translationY;

            /*
            if( ! thisUnivers.isRecord && thisUnivers.jPointerIHM > 10 && (Math.floor(thisUnivers.jPointerIHM)>  thisUnivers.ihm.bestscore) ) {
                thisUnivers.isRecord = true ;
                thisUnivers.ihm.alerteNiveau();
            }
            */

            if( ! thisUnivers.isOwnRecord && thisUnivers.jPointerIHM > 10 && ( Math.floor(thisUnivers.jPointerIHM)>  thisUnivers.ihm.bestpersonalscore ) ) {
                thisUnivers.isOwnRecord = true ;
                thisUnivers.ihm.alerteNiveau();
            }

            //X et Y sont renvoyés positifs
            return new PointF(translationX,translationY) ;
        }


        public void newGame() {
            Univers thisUnivers = this ;
            thisUnivers.iPointerIHM = 0 ;
            thisUnivers.jPointerIHM = 0 ;
            this.endJourn = false ;
            thisUnivers.data=new Hashtable<Integer, Colonne>() ;
            thisUnivers.lastCreatedX = -1 ;
            thisUnivers.oldestCreatedX = -1 ;
            thisUnivers.selectedCol = -1 ;
            thisUnivers.createTerrain(
                    0,
                    thisUnivers.ihm.discrWidth,
                    thisUnivers.jPointerIHM
            );
            thisUnivers.duck = new Duck(thisUnivers);
            thisUnivers.ignition = false ;
            thisUnivers.ihm.reset();
        }



        public void endJourney() {
            this.ihm.compteurPub++ ;
            this.endJourn = true ;
        }

        public void changeCol(int i) {
            if(this.data.containsKey(this.selectedCol)) {
                this.data.get(this.selectedCol).type = 1 ;
            }
            this.selectedCol = i ;
            this.data.get(i).type = 2 ;
        }

    }
